package com.atguigu.guli.service.sms.service.impl;

import com.atguigu.guli.common.util.FormUtils;
import com.atguigu.guli.common.util.RandomUtils;
import com.atguigu.guli.service.base.consts.ServiceConsts;
import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.sms.service.SmsService;
import com.atguigu.guli.service.sms.util.HttpUtils;
import com.atguigu.guli.service.sms.util.SmsProperties;
import com.google.gson.Gson;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SmsProperties smsProperties;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void sendCode(String mobile, Integer type) {
        boolean b = FormUtils.isMobile(mobile);
        if (!b) {
            throw new GuliException(ResultCodeEnum.LOGIN_PHONE_ERROR, new RuntimeException("输入手机不对"));
        }
        //2、判断该手机号码是否一分钟内获取过验证码
        String perminKey = ServiceConsts.MODEL_COUNT_MIN_PERFIX + mobile;
        Boolean hasKey = redisTemplate.hasKey(perminKey);
        if (hasKey) {//表示1分钟内已经获取过验证码
            throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL, new RuntimeException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL.getMessage()));
        }
        int count = 0;
        Object countObj = redisTemplate.opsForValue().get(ServiceConsts.MODEL_COUNT_DAY_PERFIX + mobile);
        if (countObj != null) {
            count = Integer.parseInt(countObj.toString());
            if (count >= 3) {//一个手机号码一天内获取验证码的次数超过3次
                throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_COUNT_LIMIT_CONTROL,
                        new RuntimeException(ResultCodeEnum.SMS_SEND_ERROR_COUNT_LIMIT_CONTROL.getMessage()));
            }
        }

        String host = smsProperties.getHost();
        String path = smsProperties.getPath();
        String method = smsProperties.getMethod();
        String appcode = smsProperties.getAppCode();
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", mobile);
        String code = RandomUtils.getFourBitRandom();
        querys.put("param", "**code**:" + code + ",**minute**:5");
        querys.put("smsSignId", smsProperties.getSmsSignId());
        querys.put("templateId", type == 1 ? smsProperties.getTemplateId1() : smsProperties.getTemplateId2());
        Map<String, String> bodys = new HashMap<String, String>();


        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            HashMap map = new Gson().fromJson(EntityUtils.toString(response.getEntity()), HashMap.class);
            if (!"0".equals(map.get("code"))) {
                throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR, new RuntimeException("验证码发送失败"));
            }
            redisTemplate.opsForValue().set(ServiceConsts.MOBEL_CODE_PERFIX + mobile, code, 10, TimeUnit.MINUTES);
            //设置1分钟内不能重复获取验证码
            redisTemplate.opsForValue().set(ServiceConsts.MODEL_COUNT_MIN_PERFIX + mobile, code, 60, TimeUnit.SECONDS);
            redisTemplate.opsForValue().increment(ServiceConsts.MODEL_COUNT_DAY_PERFIX + mobile);
            if (count == 0) {

                redisTemplate.expire(ServiceConsts.MODEL_COUNT_DAY_PERFIX + mobile, 24, TimeUnit.HOURS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
